﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Xml;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;

/// <summary>
///NginxPurge 的摘要说明
/// </summary>
public class NginxPurge
{

    static NginxPurge()
    {
        Thread thread = new Thread(Sender);
        thread.Start();
    }

   static  Queue<string> lst = new Queue<string>();

    public static void AddReg(string reg)
    {
        lock (lst)
        {
            lst.Enqueue(reg);
        }
    }

    public static void AddReg(List<string> regLst)
    {
        lock (lst)
        {
            foreach (var c in regLst)
            {
                lst.Enqueue(c);
            }
        }
    }

    static void Sender()
    {
        while (true)
        {
            try
            {
                if (lst.Count > 0)
                {
                    string xml = string.Empty;
                    while (lst.Count > 0)
                    {
                        xml += createXmlReg(lst.Dequeue());
                    }
                    xml = createXmlRoot(xml);
                    Sender(xml);
                }
            }
            catch
            {
            }
            finally
            {
                Thread.Sleep(5000);
            }
        }
    }

    static void Sender(string xml)
    {

        string str = System.Configuration.ConfigurationManager.AppSettings["NginxPurgeServers"];
        string[] servers = str.Split(',');
        foreach (var c in servers)
        {
            try
            {
                string[] a = c.Split(':');
                string ip = a[0];
                int port = int.Parse(a[1]);
                object[] objs = new object[] { ip, port, xml };
                new NginxPurge().StartClient(objs);
            }
            catch(Exception ex)
            {
                string dd = "";
            }
        }
    }

    private static string createXmlRoot(string content)
    {
        return "<root>" + content + "</root>";
    }

    private static string createXmlReg(string reg)
    {
        return "<reg>" + reg + "</reg>";
    }

    /// <summary>
    /// XML转译字符转换
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    private static string XMLZY(string str)
    {
        StringBuilder builder = new StringBuilder(str);
        builder = builder.Replace("&", "&amp;")
            .Replace("<", "&lt;")
            .Replace(">", "&gt;")
            .Replace("\"", "&quot;")
            .Replace("'", "&apos;");
        return builder.ToString();
    }
    #region "Socket"
    public class StateObject
    {
        // Client socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
    }

    // ManualResetEvent instances signal completion.
    private ManualResetEvent connectDone =
        new ManualResetEvent(false);
    private ManualResetEvent sendDone =
        new ManualResetEvent(false);
    private ManualResetEvent receiveDone =
        new ManualResetEvent(false);

    private ManualResetEvent receiveResult = new ManualResetEvent(false);
    // The response from the remote device.

    public void StartClient(object obj)
    {
        object[] strs = (object[])obj;
        int port = (int)strs[1];
        string xml = (string)strs[2];
        IPAddress ipAddress = IPAddress.Parse((string)strs[0]);
        IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
        // Create a TCP/IP socket.
        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        // Connect to the remote endpoint.
        client.Connect(remoteEP);
        Send(client, xml);
        string result = Receive(client);
        client.Close();

    }


    private string Receive(Socket client)
    {

        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = client;
        // Begin receiving the data from the remote device.
        int bytesRead = client.Receive(state.buffer);
        string response = Encoding.GetEncoding("gbk").GetString(state.buffer, 0, bytesRead);
        return response;
    }


    private void Send(Socket client, String data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.GetEncoding("gbk").GetBytes(data);
        // Begin sending the data to the remote device.
        //client.BeginSend(byteData, 0, byteData.Length, 0,
        //    new AsyncCallback(SendCallback), client);
        Send(client, byteData);
        sendDone.Set();
    }


    private void Send(Socket client, byte[] data)
    {
        client.Send(data);
    }
    #endregion
}




